package com.conselheiro.web.entidade;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import com.conselheiro.web.entidade.enumeration.Genero;
import com.conselheiro.web.entidade.enumeration.NivelUsuario;
import com.conselheiro.web.entidade.enumeration.TipoPost;


@Entity
@Table(name = "usuario")
public class Usuario implements Identificavel {

	private static final long serialVersionUID = 2517455402267145881L;
	@Id
	@GeneratedValue
	private long id;
	@Column (unique=true)
	private String login;
	private String senha;
	private String nome;
	@Enumerated(EnumType.STRING)
	private Genero genero;
	@Temporal(TemporalType.DATE)
	private Date dataNascimento;
	@ElementCollection
	   @AttributeOverrides({
	      @AttributeOverride(name="descricao", column=@Column(name="descricao")),
	      @AttributeOverride(name="pontos", column=@Column(name="pontos"))
	   })
	private Map<TipoPost, Integer> pontos;
	@ManyToMany
	private List<Relato> relatosSeguidos;
	@Enumerated (EnumType.STRING)
	private TipoAuth tipoAuth;
	private String identificadorAuth;
	@ManyToMany
	private List<Usuario> seguidores;
	private boolean novosConselhos;
	private boolean novidadesNosRelatos;
	enum TipoAuth {FACEBOOK, GOOGLE}
	
	/**
	 * De acordo com a enum {@link NivelUsuario} e a quantidade de <code>pontos</code>, 
	 * este método calcula o nível em que o usuário se encontra.
	 * 
	 * @param tipoPost
	 * @return
	 */
	public NivelUsuario getNivel(TipoPost tipoPost) {
		int pontos = this.getPontos().get(tipoPost);
		for (NivelUsuario nivel : NivelUsuario.values()) {
			if (pontos <= nivel.getPontuacaoMaxima()) {
				return nivel;
			}
		}
		return null;
	}
	
	public boolean isSegueRelato(Relato relato) {
		return this.getRelatosSeguidos().contains(relato);
	}
	
	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Genero getGenero() {
		return genero;
	}

	public void setGenero(Genero genero) {
		this.genero = genero;
	}

	public Date getDataNascimento() {
		return dataNascimento;
	}

	public void setDataNascimento(Date dataNascimento) {
		this.dataNascimento = dataNascimento;
	}
	
	@SuppressWarnings("deprecation")
	@Transient
	public int getIdade(){
		return new Date().getYear() - getDataNascimento().getYear();
	}

	public Map<TipoPost, Integer> getPontos() {
		return pontos;
	}

	public void setPontos(Map<TipoPost, Integer> pontos) {
		this.pontos = pontos;
	}

	public List<Relato> getRelatosSeguidos() {
		return relatosSeguidos;
	}

	public void setRelatosSeguidos(List<Relato> relatosSeguidos) {
		this.relatosSeguidos = relatosSeguidos;
	}

	public TipoAuth getTipoAuth() {
		return tipoAuth;
	}

	public void setTipoAuth(TipoAuth tipoAuth) {
		this.tipoAuth = tipoAuth;
	}

	public String getIdentificadorAuth() {
		return identificadorAuth;
	}

	public void setIdentificadorAuth(String identificadorAuth) {
		this.identificadorAuth = identificadorAuth;
	}

	public List<Usuario> getSeguidores() {
		return seguidores;
	}

	public void setSeguidores(List<Usuario> seguidores) {
		this.seguidores = seguidores;
	}

	public boolean isNovosConselhos() {
		return novosConselhos;
	}

	public void setNovosConselhos(boolean novosConselhos) {
		this.novosConselhos = novosConselhos;
	}

	public boolean isNovidadesNosRelatos() {
		return novidadesNosRelatos;
	}

	public void setNovidadesNosRelatos(boolean novidadesNosRelatos) {
		this.novidadesNosRelatos = novidadesNosRelatos;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (id ^ (id >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Usuario other = (Usuario) obj;
		if (id != other.id)
			return false;
		return true;
	}
}
